#include <iostream>
using namespace std;

struct Teacher
{
        char name[64];
        int age;
};

//1.
//指针所指向的内存空间 不能被修改
int operatorTeacher01(const Teacher *pT){
       //pT->age = 10;
        return 0;
}

//指针变量本身 不能被修改
int operatorTeacher01(Teacher * const pT){
        pT->age = 10;
        //pT = NULL;
        return 0;
}

//指针指向的内存空间和指针都不能被修改
int operatorTeacher03(const Teacher * const pT){
        //pT->age = 10;
        //pT = NULL;
        printf("age:%d\n", pT->age);
        return 0;
}

//const 回顾
int main01(int argc, char const *argv[]){
/*
        const int a;
        int const b; //一样

        const int *c; //const修饰的是指针指向的内存空间,不能被修改
        int * const d; // 指针变量不能被修改

        const int * const e; //指针指向的内存空间和指针都不能被修改
*/
        Teacher t1;
        t1.age = 33;
        operatorTeacher03(&t1);
        return 0;
}

//2.
//c语言中的 const是一个冒牌货
//c++语言中 const是一个真正的常量

//原因分析

int main02(int argc, char const *argv[])
{
        //好像 a是一个常量
        const int a = 10; //c++编译器会用一个符号表记录起来
        //a = 11;
        int *p = NULL;
        p = (int *)&a;  //这个操作在c++中单独开辟了一个空间 跟 a的空间没有关系

        *p = 20;

        printf("a = %d \n", a);  // c编译器后 a = 20 c++编译器 a = 10 
        printf("*p = %d \n", *p);  //
        return 0;
}

//3.
//const 分配内存的时机 编译器编译期间就分配了
int main03(int argc, char const *argv[]){
        
        //好像 a是一个常量
        int a;
        const int b = 10;
        int c; 

        printf("&a:%d, &b:%d &c:%d \n", &a , &b, &c);

        return 0;
}

//4.
//const 和 #define 的相同之处
//#define d 20;   //编译器与预处理期间就处理的
//const 常量是编译期间就处理的,提供类型检查和作用域检查
int main04(int argc, char const *argv[]){
        //int a = 10;
        //int b = 20;
        //int array[a+b]; //c和c++编译器 不支持这种语法现象 编译不通过
                                      //但是linux内核里面是成立的; 原因 编译linux内核的gcc编译器支持.
        
        const int c = 10;
        const int d = 20;
        int array[c+d]; //编译通过
        return 0;
}

//5 const定义的变量 是编译期间就处理的,提供类型检查和作用域检查
void fun1(){
        #define a 10
        const int b = 20;
        //#undef a; //卸载宏定义
}

void fun2(){
        printf("a = %d \n", a); //卸载宏定义a 就报错 不卸载不会报错
        //printf("b = %d \n", b); //const是有作用域的 会报错 c++编译不通过
}

int main(int argc, char const *argv[]){
        fun1();
        fun2();
        return 0;
}
